ctxt->kernel_ss = ctxt->user_regs.ss;
ctxt->kernel_sp = ctxt->user_regs.esp;
- ctxt->flags = VGCF_in_kernel_X86_32;
+ ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32;
if ( dom->parms.pae == 2 /* extended_cr3 */ ||
dom->parms.pae == 3 /* bimodal */ )
ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
ctxt->kernel_ss = ctxt->user_regs.ss;
ctxt->kernel_sp = ctxt->user_regs.esp;
- ctxt->flags = VGCF_in_kernel_X86_64;
+ ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
/* Set [er]ip in the way that's right for Xen */
if ( strstr(caps, "x86_64") )
+ {
ctxt->c64.user_regs.rip = elf_uval(&elf, elf.ehdr, e_entry);
+ ctxt->c64.flags = VGCF_online;
+ }
else
+ {
ctxt->c32.user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
+ ctxt->c32.flags = VGCF_online;
+ }
return 0;
memset(&launch_domctl, 0, sizeof(launch_domctl));
launch_domctl.domain = (domid_t)domid;
- launch_domctl.u.vcpucontext.vcpu = 0;
+ launch_domctl.u.vcpucontext.vcpu = 0;
set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, &ctxt.c);
launch_domctl.cmd = XEN_DOMCTL_setvcpucontext;
rc = xc_domctl(xc_handle, &launch_domctl);
uint64_t vcpumap = 1ULL;
unsigned int max_vcpu_id = 0;
+ int new_ctxt_format = 0;
max_pfn = nr_pfns;
}
if (j == -2) {
+ new_ctxt_format = 1;
if (!read_exact(io_fd, &max_vcpu_id, sizeof(int)) ||
(max_vcpu_id >= 64) ||
!read_exact(io_fd, &vcpumap, sizeof(uint64_t))) {
goto out;
}
+ if ( !new_ctxt_format )
+ ctxt.flags |= VGCF_online;
+
if (i == 0) {
/*
* Uncanonicalise the suspend-record frame number and poke
/* This overrides some registers. */
vcpu_init_regs(v);
- /* Don't redo final setup */
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ /* Don't redo final setup. Auto-online VCPU0. */
+ if (!test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
+ (v->vcpu_id == 0))
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
+
return 0;
}
printk("Dom0: 0x%lx\n", (u64)dom0);
set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
/* Build firmware.
Note: Linux kernel reserve memory used by start_info, so there is
d->shared_info->wc_nsec = dom0->shared_info->wc_nsec;
d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase;
- set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ /* Auto-online VCPU0 when it is initialised. */
+ if ( !test_and_set_bit(_VCPUF_initialised, &v->vcpu_flags) &&
+ (v->vcpu_id == 0) )
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
cpu_init_vcpu(v);
ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr);
set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
rc = 0;
}
if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
- return 0;
+ goto out;
memset(v->arch.guest_context.debugreg, 0,
sizeof(v->arch.guest_context.debugreg));
update_cr3(v);
+ out:
+ if ( flags & VGCF_online )
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
+ else
+ set_bit(_VCPUF_down, &v->vcpu_flags);
return 0;
#undef c
}
update_domain_wallclock_time(d);
set_bit(_VCPUF_initialised, &v->vcpu_flags);
+ clear_bit(_VCPUF_down, &v->vcpu_flags);
/*
* Initial register values:
v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
v->runstate.state_entry_time = NOW();
- if ( (vcpu_id != 0) && !is_idle_domain(d) )
+ if ( !is_idle_domain(d) )
set_bit(_VCPUF_down, &v->vcpu_flags);
if ( sched_init_vcpu(v, cpu_id) != 0 )
case XEN_DOMCTL_unpausedomain:
{
struct domain *d = rcu_lock_domain_by_id(op->domain);
+
ret = -ESRCH;
- if ( d != NULL )
- {
- ret = -EINVAL;
- if ( (d != current->domain) && (d->vcpu[0] != NULL) &&
- test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) )
- {
- domain_unpause_by_systemcontroller(d);
- ret = 0;
- }
- rcu_unlock_domain(d);
- }
+ if ( d == NULL )
+ break;
+
+ domain_unpause_by_systemcontroller(d);
+ rcu_unlock_domain(d);
+ ret = 0;
}
break;
#define VGCF_failsafe_disables_events (1<<_VGCF_failsafe_disables_events)
#define _VGCF_syscall_disables_events 4
#define VGCF_syscall_disables_events (1<<_VGCF_syscall_disables_events)
+#define _VGCF_online 5
+#define VGCF_online (1<<_VGCF_online)
unsigned long flags; /* VGCF_* flags */
struct cpu_user_regs user_regs; /* User-level CPU registers */
struct trap_info trap_ctxt[256]; /* Virtual IDT */
"VGCF_failsafe_disables_events",
"_VGCF_syscall_disables_events",
"VGCF_syscall_disables_events",
+ "_VGCF_online",
+ "VGCF_online",
# ia64
"VGCF_EXTRA_REGS",